home *** CD-ROM | disk | FTP | other *** search
- Path: news.wwa.com!rmartin
- From: rmartin@oma.com (Robert C. Martin)
- Newsgroups: comp.object,comp.lang.c++,comp.ai.alife,sci.comp-aided
- Subject: Re: [Q] Growing Objects
- Date: 20 Jan 1996 15:34:28 GMT
- Organization: Object Mentor
- Message-ID: <RMARTIN.96Jan20093428@rcm.oma.com>
- References: <30FE8297.41C6@bme.jhu.edu>
- NNTP-Posting-Host: rmartin.ip.wwa.com
- In-reply-to: Harold Bien's message of Thu, 18 Jan 1996 12:25:43 -0500
-
- In article <30FE8297.41C6@bme.jhu.edu> Harold Bien <hbien@bme.jhu.edu> writes:
-
- This "Run" function will call another function indirectly. In
- simpler terms, it "opens up a box labelled RunMe" and whatever was in
- the box then gains control, and here's where the exciting part comes.
- The function which is "in the box" _CHANGES_OVER_TIME. Therefore, the
- functionality of the object "Cell" changes over time.
-
- What you have described is known as a finite state machine. A finite
- state machine reacts to particular events in ways that depend upon the
- state of the machine. In your case, you have only one event: Run; but
- you have many states.
-
- The class Cell has a function Run() which takes no arguments but
- calls another function through a pointer to a member function. Then,
- when that member function runs, it updates a variable 'age' and checks
- to see if it is mature. If so, then it will change the pointer to point
- to another function.
-
- You can use pointers to member functions to control your state
- machine. However I recommend against it. It may be, after some time,
- that you find that you need other events beside 'run'. For example,
- you may wish to tell each cell to "print"; and would like the behavior
- of "print" to depend upon the state of the cell. Other events seem
- likely as well: RespondToLight, RespondToHunger, RespondToAttack,
- etc. Each of these stimuli will very likely depend upon the state.
- If you use the member function approach, you will find that every time
- the cell changes state, you will have to shuttle around many pointers
- to member functions. The chances of error are high.
-
- There is a better way, and one that has been used for many years to
- implement finite state machines.
-
- class Cell;
-
- class CellState
- {
- public:
- virtual void Run(Cell*) = 0;
- };
-
- class Cell
- {
- public:
- void Run() {itsState->Run(this);}
- private:
- CellState* itsState;
- };
-
- class Young : public CellState
- {
- public:
- virtual void Run(Cell*);
- };
-
- class Old : public CellState
- {
- public:
- virtual void Run(Cell*);
- };
-
-
- You ought to be able to see how it works from this explanation.
- Instead of having the Cell point to a member to a function, you have
- it point to an instance of an abstract class. Instead of changing the
- pointer to the member function when the cell changes state, you change
- the instance that is being pointed to.
-
- Now you can add new events to the abstract base class at will. The
- code which changes the state of the Cell will not have to manage a
- bunch of pointers to members. It need only manage a single pointer to
- a CellState derivative.
-
- ------
-
- The above uses a design pattern known as 'State'. You can read about
- it in "Design Patterns" by Gamma et. al. Addison Wesley.
-
- The code above can be automatically generated with a tool that I wrote
- many years ago, and which I have been offering as public domain on the
- net. The name of this tool is SMC. SMC generates the C++ code that
- implements a finite state machine. The C++ code that is generated
- uses the state pattern as above.
-
- If anybody is interested in receiving this tool, send me email and
- i'll email the source code to you.
-
- --
- Robert Martin | Design Consulting | Training courses offered:
- Object Mentor Assoc.| rmartin@oma.com | OOA/D, C++, Advanced OO
- 14619 N. Somerset Cr| Tel: (708) 918-1004 | Mgt. Overview of OOT
- Green Oaks IL 60048 | Fax: (708) 918-1023 | Development Contracts.
-
-